package com.item.schedule.confing;

import com.zaxxer.hikari.HikariDataSource;
import org.quartz.Scheduler;
import org.quartz.spi.JobFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jdbc.datasource.init.DataSourceInitializer;
import org.springframework.jdbc.datasource.init.DatabasePopulator;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

import javax.sql.DataSource;
import java.io.IOException;
import java.util.Properties;

/**
 * @author zhang-rongyao
 * @version V1.0
 * @Package com.item.schedule.confing
 * @date 2021/8/4 10:44
 */
@Configuration
public class QuartzConfig {

    private Logger log = LoggerFactory.getLogger(QuartzConfig.class);

    @Autowired
    private JobFactory jobFactory;

    //使用自定义数据源  Quartz数据持久化到我们指定的数据库
    //下载与Quartz相关的表 官网地址：http://www.quartz-scheduler.org/downloads/
    //然后在源码quartz-2.3.0/docs/dbTables目录下可以找到所有数据库的建表语句，找到2.3.0版mysql innoDB的建表脚本 执行脚本建表
    /*@Autowired
    DataSource dataSource;*/


    /**
     * 使用自定义的数据源
     * @return
     * @throws IOException
     */
    @Bean
    public DataSource quartzSource() throws IOException {
        HikariDataSource dataSource = new HikariDataSource();
        Properties properties = quartzProperties();
        dataSource.setDriverClassName(properties.getProperty("org.quartz.dataSource.myDS.driver"));
        dataSource.setJdbcUrl(properties.getProperty("org.quartz.dataSource.myDS.URL"));
        dataSource.setUsername(properties.getProperty("org.quartz.dataSource.myDS.user"));
        dataSource.setPassword(properties.getProperty("org.quartz.dataSource.myDS.password"));
        return dataSource;
    }

    /**
     * 执行脚本 持久化定时任务的11张表
     * @param dataSource
     */
    public void initDataBase(DataSource dataSource) {
        log.info("============== init quartz database started ==============");
        try {
            //加载SQL
            //使用DataSourceInitializer初始化
            DataSourceInitializer dsi = new DataSourceInitializer();
            dsi.setDataSource(dataSource);
            final ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
            populator.addScripts(new ClassPathResource("sql/tables_mysql_innodb.sql"));
            //populator.setSeparator("$$$"); // 分隔符，默认为;
            dsi.setDatabasePopulator(populator);
            dsi.setEnabled(true);
            dsi.afterPropertiesSet();
            log.info("============== init quartz database succeed ==============");
        } catch (Exception e) {
            log.error("init quartz database failed:{}", e.getMessage());
        }
    }


    @Bean
    public Properties quartzProperties() throws IOException {
        PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
        propertiesFactoryBean.setLocation(new ClassPathResource("quartz.properties"));
        propertiesFactoryBean.afterPropertiesSet();
        return propertiesFactoryBean.getObject();
    }

    @Bean
    public SchedulerFactoryBean schedulerFactoryBean() throws IOException {
        //初始化数据库
        initDataBase(quartzSource());
        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
        schedulerFactoryBean.setDataSource(quartzSource());
        schedulerFactoryBean.setSchedulerName("PF-Scheduler");
        schedulerFactoryBean.setStartupDelay(30);
        schedulerFactoryBean.setApplicationContextSchedulerContextKey("applicationContextKey");
        //可选，QuartzScheduler 启动时更新己存在的Job，这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了
        schedulerFactoryBean.setOverwriteExistingJobs(true);
        schedulerFactoryBean.setAutoStartup(true);
        schedulerFactoryBean.setQuartzProperties(quartzProperties());
        schedulerFactoryBean.setJobFactory(jobFactory);
        return schedulerFactoryBean;
    }

    // 创建schedule
    @Bean(name = "scheduler")
    public Scheduler scheduler() throws IOException {
        return schedulerFactoryBean().getScheduler();
    }
}
